import re

from django.urls import reverse
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin

from oracle.models import OSettingUrl
from oracle.base.baseview import render_handler


class OracleMiddleware(MiddlewareMixin):
    """
    用户权限信息校验
    """

    def process_request(self, request):
        """
        当用户请求进入时触发执行
        :param request:
        :return:
        """
        # 0. 是否启用权限验证功能
        if not hasattr(settings, 'PERMISSION_AUTHENTICATE_ENABLE') or not settings.PERMISSION_AUTHENTICATE_ENABLE:
            return None
        urls_queryset = OSettingUrl.objects.filter(status=0)
        # 1. 获取当前用户请求的url
        current_url = request.path_info
        # 白名单判断
        white_list_list = urls_queryset.filter(type=0, status=0).values_list('url', flat=True)
        white_list_list = set(settings.VALID_URL_LIST) | set(white_list_list)
        for white_list_url in white_list_list:
            reg = f"^{white_list_url}$"
            if re.match(reg, current_url):
                # 是白名单不拦截
                return None
        # 2. 获取当前用户在session中保存的权限列表
        permisssion_dict = request.session.get(settings.PERMISSION_SESSION_KEY)
        # 没有权限列表，说明没有登录
        if not permisssion_dict:
            status = "user_not_login"
            data = {"title": "没有访问权限", "href": reverse("login"), "button_text": "返回登陆页"}
            return render_handler(request, status, data=data)
        # 3. 只要登录，不用权限校验都能访问的url
        white_list_after_login = urls_queryset.filter(type=2, status=0).values_list('url', flat=True)
        white_list_after_login = set(settings.NO_PERMISSION_LIST) | set(white_list_after_login)
        for url in white_list_after_login:
            reg = f"^{url}$"
            if re.match(reg, current_url):
                return None
        # 4. 权限信息的匹配
        flag = False
        for item in permisssion_dict.values():
            reg = f'^{item["url"]}$'
            if re.match(reg, current_url):
                flag = True
                break
        # 没有匹配权限，说明没有权限访问
        if not flag:
            status = "access_denied"
            data = {"title": "没有访问权限", "href": reverse("index"), "button_text": "返回首页"}
            return render_handler(request, status, data=data)
